home *** CD-ROM | disk | FTP | other *** search
/ User's Choice Windows CD / User's Choice Windows CD (CMS Software)(1993).iso / windows4 / pcproj.zip / NODE.CLS < prev    next >
Text File  |  1988-11-22  |  6KB  |  228 lines

  1. /* Node is a formal class for things that are connected as part
  2.    of a Network.  Node defines the connection protocol. Nodes
  3.    know their inputs and outputs, their network and their
  4.    relative display position in the network. */!!
  5.  
  6. inherit(Object, #Node, #(name     /* node name */
  7. desc     /* longer description */
  8. inputs   /* collection of inputs */
  9. outputs  /* collection of outputs */
  10. network  /* who "owns" the node */
  11. x        /* display x position */
  12. y        /* display y position */), 2, nil)!!
  13.  
  14. now(NodeClass)!!
  15.  
  16. /* Create and initialize a new node. */
  17. Def  new(self)
  18.   ^init(new(self:Behavior));
  19. } !! 
  20.  
  21. now(Node)!!
  22.  
  23. /* Return the network the node belongs to. */
  24. Def  getNetwork(self)
  25. {
  26.   ^network;
  27. }!!
  28.  
  29. /* Return a point of the x and y instance variables. */
  30. Def  pos(self)
  31. {
  32.   ^point(x, y);
  33. }!!
  34.  
  35. /* Get the description. */
  36. Def  getDesc(self)
  37. { ^desc;
  38. }   !!
  39.  
  40. /* Get the x position. */
  41. Def  x(self)
  42. { ^x;
  43. }   !!
  44.  
  45. /* Get the y position. */
  46. Def  y(self)
  47. { ^y;
  48. }   !!
  49.  
  50. /* Reset the position when disconnecting.
  51.       x : the maximum level of any inputs + 1
  52.       y : don't change it since it's already set
  53.    If the x position changes, propogate it.
  54.    Tell the network also.
  55. */
  56. Def  resetPosn(self, inputNode | oldPos)
  57. {  
  58.   oldPos := pos(self);
  59.   if x <= x(inputNode) + 1
  60.     x := 0;
  61.     do(inputs,
  62.       {using(input) x := max(x(input)+1, x);
  63.     });
  64.     do(outputs,
  65.       {using(output) 
  66.        if inputNode <> output cand self <> output  /* avoid loop */
  67.          resetPosn(output, self);
  68.        endif;
  69.     });
  70.   endif;
  71.   if x+y = 0    /* completely disconnected */
  72.      y := 1;    /* use a "safe" location */
  73.   endif;
  74.   /* the new position could conflict with something else in the project */
  75.   if oldPos <> pos(self)
  76.     resetPosn(network, self, oldPos);
  77.   endif;
  78. }!!
  79.  
  80. /* Set the position when connecting.
  81.       x : the maximum level of any inputs + 1
  82.       y : the y of input plus the output number
  83.    If the x position changes, propogate it.
  84.    Also, tell the network.
  85.  */
  86. Def  setPosn(self, inputNode | oldPos)
  87.   oldPos := pos(self);
  88.   
  89.   /* If the node position has not been set, set it's y. */
  90.   if x = 0
  91.     y := max(0,y(inputNode) + size(getOutputs(inputNode)) - 1);
  92.   endif;
  93.   
  94.   /* If the level increases, set it and propogate. */
  95.   if x(inputNode) + 1 > x
  96.     x := x(inputNode) + 1;
  97.     do(outputs,
  98.       {using(output)    
  99.        if inputNode <> output cand self <> output  /* avoid loop */
  100.           setPosn(output, self);
  101.        endif;
  102.     });
  103.   endif;
  104.   /* the new position could conflict with something else in the project */
  105.   if oldPos <> pos(self)
  106.     resetPosn(network, self, oldPos);
  107.   endif;
  108. }!!
  109.  
  110. /* Set the network the node belongs to. */
  111. Def  setNetwork(self, aNet)
  112. {
  113.   network := aNet;
  114. }!! 
  115.  
  116. /* To disconnect node n1->n2, n1's outputs must remove n2. */
  117. Def  removeOutputs(self, aNode)
  118. { remove(outputs, aNode);
  119. }  !! 
  120.  
  121. /* To disconnect node n1->n2, n2's inputs must remove n1. */
  122. Def  removeInputs(self, aNode)
  123. { remove(inputs, aNode);
  124. }  !!
  125.  
  126. /* Disconnect n1->n2 by updating n1's outputs and n2's inputs. 
  127.    The node n2 position must be reset based on its former input. */
  128. Def  disconnect(self, aNode)
  129. { removeInputs(aNode, self);
  130.   removeOutputs(self, aNode);
  131.   resetPosn(aNode, self);
  132. } !!
  133.  
  134. /* Recursively show all outputs, level by level.
  135.    Keep track of visited nodes to avoid looping. 
  136.    n is the level for formatting.  CurPos is a
  137.    global of current print position for formatting.
  138.    Note: This is for testing networks during development.
  139. */
  140. Def  show(self, visited, n)
  141.   do(n-CurPos,                      /* adjust position */
  142.     {using(i) print("      ");
  143.   });
  144.   CurPos:=n;                        /* update position */
  145.   print(self);                      /* show node */
  146.   if size(outputs) == 0 then
  147.      printLine("");print("   ");
  148.      CurPos := 0;
  149.   else
  150.      CurPos := CurPos +1;
  151.   endif;
  152.   do(outputs,                       /* show outputs */
  153.     {using(elem) 
  154.       if(not(elem in visited))      /* not yet shown */
  155.         add(visited, elem);         /* avoid looping */ 
  156.         show(elem, visited, n+1);   /* recurse */
  157.       else
  158.         printLine("");
  159.         print("   ");
  160.         CurPos := 0;                /* reset position */
  161.       endif;
  162.     });
  163. } !!
  164.  
  165. /* pass through method to return a node's outputs */
  166. Def  getOutputs(self)
  167. { ^outputs;
  168. } !! 
  169.  
  170. /* pass through method to return a node's inputs */
  171. Def  getInputs(self)
  172. { ^inputs;
  173. } !!
  174.  
  175. /* To connect node n1->n2, n1's outputs must contain n2. */
  176. Def  addOutputs(self, aNode)
  177.   add(outputs, aNode);
  178. } !!
  179.  
  180. /* To connect n1->n2, n2's inputs must contain n1. */
  181. Def  addInputs(self, aNode)
  182.   add(inputs, aNode);
  183. } !!
  184.  
  185. /* Connect self->aNode by updating self's outputs and 
  186.    aNode's inputs. Also, aNode should know it's network
  187.    and the position should be set based on it's input. */
  188. Def  connect(self, aNode)
  189. { addInputs(aNode, self);
  190.   addOutputs(self, aNode);
  191.   setNetwork(aNode, network);
  192.   setPosn(aNode, self);
  193. } !!
  194.  
  195. /* Set the name. */
  196. Def  setName(self, aName)
  197. { name := aName;
  198. }   !!
  199.  
  200. /* Get the name. */
  201. Def  getName(self)
  202. { ^name;
  203. }   !!
  204.  
  205. /* Initialize a new node.  Set the name, desc
  206.    and position to safe values.  Keep track of
  207.    our connections in inputs and outputs.  These
  208.    sets will grow as necessary. */
  209. Def  init(self)
  210. { name := desc:= "";
  211.   x := y := 0;
  212.   inputs := new(Set, 2);
  213.   outputs := new(Set, 2);
  214. }  !!
  215.  
  216. /* Print the node.  
  217.    This is used during development only. */
  218. Def  printOn(self, aStrm)
  219.   printOn(asString(class(self))+":"+asString(name), aStrm);
  220. }!! 
  221.  
  222.